﻿/*------------------------------------------------------------------------

CXXLOBJECT.HPP v3.5

Copyright 楊志賢 CxxlMan, 2008 - 2013
All Rights Reserved


------------------------------------------------------------------------*/


#if !defined(__CXXLOBJECT_HPP_CxxlMan)
#define __CXXLOBJECT_HPP_CxxlMan

#include "DLLDEF.HPP"
#include "CRITICAL.HPP"
#include <stddef.h>


#if defined(_CXXLOBJECT_DLLEXPORT)
#define CXXLOBJECT_DLLEXPORT CXXL_DLLEXPORT
#else
#define CXXLOBJECT_DLLEXPORT CXXL_DLLIMPORT
#endif

class YanLuoWang;

namespace CxxlMan
{

class CXXLOBJECT_DLLEXPORT Smart_Ptr_Base;
class CXXLOBJECT_DLLEXPORT cxxlObject;
class CXXLOBJECT_DLLEXPORT IcxxlObject;
class CXXLOBJECT_DLLEXPORT ICentralizedMgr;
class CXXLOBJECT_DLLEXPORT ISpirit;


extern CXXLOBJECT_DLLEXPORT ISpirit *Spirit_Urgent; // 同步處理
extern CXXLOBJECT_DLLEXPORT ISpirit *Spirit_Easy;   // 非同步處理
extern CXXLOBJECT_DLLEXPORT cxxlObject *rootObject; // ...

/*
  提供給 cxxlObject 選用生死處理方式的上層介面，
  延伸實例須採用 Singleton 設計模式
*/
class CXXLOBJECT_DLLEXPORT ISpirit
{
  virtual void cxxlFASTCALL ToDelete(cxxlObject *Obj) const = 0;
  virtual void cxxlFASTCALL ObjOver() const = 0;
  virtual ISpirit *cxxlFASTCALL GetSpirit() const = 0;

  virtual void cxxlFASTCALL Lock() const {}
  virtual void cxxlFASTCALL UnLock() const {}


protected:
  // 類似 Bridge Patterns 的用法，方便 Proxy Patterns 的實作
  void CallToDelete(const ISpirit *spirit, cxxlObject *Obj) const
  {
    spirit->ToDelete(Obj);
  }

  ISpirit(){}           // Constructor
  virtual ~ISpirit()    // Destructor
  {
  }

  ISpirit *cxxlFASTCALL GetSpirit(const ISpirit *pSpirit_Arg) const
  {
    return pSpirit_Arg->GetSpirit();
  }

  inline void cxxlFASTCALL cxxlObjectUnLock(cxxlObject *Obj) const;
  inline bool cxxlFASTCALL GetFlag(cxxlObject *Obj) const;
  inline void cxxlFASTCALL SetFlag(cxxlObject *Obj,bool Flag) const;


public:

  friend class CXXLOBJECT_DLLEXPORT cxxlObject;
};


/*


class CXXLOBJECT_DLLEXPORT IcxxlObject
{

public:
  IcxxlObject(){} // Constructor
  virtual ~IcxxlObject(){} // Destructor

//  virtual void cxxlFASTCALL cxxlObjectLock() = 0;
//  virtual void cxxlFASTCALL cxxlObjectUnLock() = 0;
//  virtual bool cxxlFASTCALL GetFlag() const = 0;
//  virtual void cxxlFASTCALL SetFlag(bool V) = 0;
//  virtual bool cxxlFASTCALL Trial() = 0;
//  virtual void cxxlFASTCALL ReSet_toFind() = 0;
//  virtual void cxxlFASTCALL ClearHost() = 0;
  virtual void cxxlFASTCALL YanLuoWang_ChkIn() {}
  virtual void cxxlFASTCALL YanLuoWang_ChkOut() {}
};

*/

class CXXLOBJECT_DLLEXPORT cxxlObject //:private IcxxlObject
{
  CriticalSec csObject;

  ISpirit *Spirit; // 由它決定生死方式

  void cxxlFASTCALL SetSpirit(ISpirit *spirit)
  {
    Spirit = spirit;
  }

  virtual void * cxxlFASTCALL GetPreserve2() const
  {
    return NULL;
  }

  // 擁有此物件的所有智慧指標的串列
  Smart_Ptr_Base *ptrown;

  // 供 ISpirit_Easy 利用，被放入待刪處理佇列設為 true
  // cxxlObject::Trial() 處理過會設回 false
  bool Spirit_Flag;

  // 未放入過 Smart_Ptr 皆視為 rootObject
  // 這樣設計的目的是為了讓此物件在未放入 Smart_Ptr 之前也能持有和確保子物件
  bool isRoot;
  virtual void cxxlFASTCALL False_isRoot();



/* 供 ISpirit 叫用 */

  virtual void cxxlFASTCALL YanLuoWang_ChkIn() {}
  virtual void cxxlFASTCALL YanLuoWang_ChkOut() {}

  void cxxlFASTCALL cxxlObjectLock()
  {
    csObject.Enter();
  }

  void cxxlFASTCALL cxxlObjectUnLock()
  {
    csObject.Leave();
  }

  bool cxxlFASTCALL GetFlag() const
  {
    return Spirit_Flag;
  }

  void cxxlFASTCALL SetFlag(bool Flag)
  {
    Spirit_Flag = Flag;
  }

  void cxxlFASTCALL ClearHost();

  // 找不到 rootObject 回覆 true
  bool cxxlFASTCALL Trial();
  void cxxlFASTCALL ReSet_toFind();
  bool (cxxlFASTCALL cxxlObject::*toFind)();  // 這三個架構成 State 設計模式
  bool cxxlFASTCALL Find_rootObject();        //
  bool cxxlFASTCALL Finded();                 //



/* 供 Smart_Ptr_Base 叫用 */

  // 加入指定的智彗指標到串列中
  void cxxlFASTCALL AttachPtr(Smart_Ptr_Base *Ptr);

  // 從串列中移除指定的智彗指標
  void cxxlFASTCALL DetachPtr(Smart_Ptr_Base *Ptr);


  // non-copyable
  cxxlObject( const cxxlObject& );
  const cxxlObject& operator=( const cxxlObject& );

protected:
  cxxlObject(ISpirit *spirit)   // Constructor
  {
    isRoot = true;
    Spirit = spirit;
    ptrown = NULL;
    Spirit_Flag = false;
    toFind = &CxxlMan::cxxlObject::Find_rootObject;
  }

  ISpirit *cxxlFASTCALL GetSpirit() const
  {
    return Spirit->GetSpirit();
  }

  void cxxlFASTCALL LockSpirit() const
  {
    Spirit->Lock();
  }

  void cxxlFASTCALL UnLockSpirit() const
  {
    Spirit->UnLock();
  }

  virtual ~cxxlObject()  // Destructor
  {
    // delete Spirit;
    Spirit->ObjOver();
  }

public:

  friend class ISpirit;
  friend class Smart_Ptr_Base;
  friend class CXXLOBJECT_DLLEXPORT ICentralizedMgr;
  friend class ::YanLuoWang;
};

inline void cxxlFASTCALL ISpirit::cxxlObjectUnLock(cxxlObject *Obj) const
{
  Obj->cxxlObjectUnLock();
}

inline bool cxxlFASTCALL ISpirit::GetFlag(cxxlObject *Obj) const
{
  return Obj->GetFlag();
}

inline void cxxlFASTCALL ISpirit::SetFlag(cxxlObject *Obj,bool Flag) const
{
  Obj->SetFlag(Flag);
}

class CXXLOBJECT_DLLEXPORT ICentralizedMgr
{
protected:

  void cxxlFASTCALL SetSpirit(cxxlObject *Obj, ISpirit *spirit)
  {
    Obj->SetSpirit(spirit);
  }

  ISpirit * cxxlFASTCALL GetSpirit(const cxxlObject *Obj)
  {
    return Obj->GetSpirit();
  }

  ISpirit * cxxlFASTCALL GetSpiritSelf(const cxxlObject *Obj)
  {
    return Obj->Spirit;
  }

  void * cxxlFASTCALL GetPreserve2(const cxxlObject *Obj)
  {
    return Obj->GetPreserve2();
  }

public:
  // Constructor
  ICentralizedMgr()
  {}

  // Destructor
  virtual ~ICentralizedMgr()
  {}

};


}   /* namespace CxxlMan */

#endif
